<?php
/**
 * 通用方法
 *
 * Author:李强 EdwinLee
 * Company:上海煦鸣网络科技有限公司
 * Time: 2018-01-10 21:25
 */

namespace App\Services\Service;


use App\Facades\QcloudCos;
use GuzzleHttp\Client;
use Illuminate\Http\File;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\URL;
use Intervention\Image\Facades\Image;
use SimpleSoftwareIO\QrCode\Facades\QrCode;

class Helper
{
    /**
     * 异常处理
     *
     * @param $request
     * @param $message
     * @param $guard 'admin','web'...
     * @param $statusCode 403无权限 404找不到配置项
     * @return \Illuminate\Http\JsonResponse|\Illuminate\Http\Response
     */
    public static function errorHandle($request, $message, $guard = 'user', $statusCode = 403, $pageData = [])
    {
        /*
         * 判断是否为ajax请求
         */
        $is_ajax = ($request->ajax() || $request->wantsJson()) ? true : false;
        //进行判断目前访问请求是否被允许
        $previousUrl = URL::previous();
        if ($is_ajax) {
            return response()->json([
                'code' => 0,
                'message' => $message,
                'data' => [
                    'jump_url' => $previousUrl
                ]
            ]);
        } else {
            $view_name = 'errors.' . $guard . '.' . $statusCode;
            if (!view()->exists($view_name)) {
                $view_name = 'errors.' . $guard . '.error';
                return response()->view($view_name, $pageData);
            }
            return response()->view($view_name, compact('previousUrl', 'message'));
        }
    }

    /**
     * 返回错误信息
     *
     * @param $request
     * @param $message
     * @param string $redirect
     * @return \Illuminate\Http\JsonResponse|\Illuminate\Http\Response
     */
    public static function warning($request, $message, $redirect = '')
    {
        /*
         * 判断是否为ajax请求
         */
        $is_ajax = ($request->ajax() || $request->wantsJson()) ? true : false;
        //进行判断目前访问请求是否被允许
        if ($redirect == '') {
            $previousUrl = URL::previous();
        } else {
            $previousUrl = $redirect;
        }
        if ($is_ajax) {
            return response()->json([
                'code' => 0,
                'message' => $message,
                'data' => [
                    'jump_url' => $previousUrl
                ]
            ]);
        } else {
            $view_name = 'home.member.error_message';
            $topmenu = '';
            return response()->view($view_name, compact('previousUrl', 'message', 'topmenu'));
        }
    }

    /**
     * 获取请求数据
     *
     * @param $_inputs 所有请求参数
     * @param $fields
     * @return array
     */
    public static function getInputs($_inputs, $fields = [])
    {
        $inputs = [];
        foreach ($fields as $field => $default) {
            if (isset($_inputs[$field])) {
                $inputs[$field] = $_inputs[$field];
            } else {
                $inputs[$field] = $default;
            }
        }
        return $inputs;
    }

    /**
     * 根据查询请求输入生成url查询串
     *
     * @param array $inputs
     * @return string
     */
    public static function getQueryUri($inputs = [])
    {
        $query_url = "";
        if (!empty($inputs)) {
            foreach ($inputs as $field => $value) {
                $query_url .= '&' . $field . '=' . $value;
            }
        }
        return '?' . ltrim($query_url, '&');
    }

    /**
     * 判断是否为关联数组
     *
     * @param $arr
     * @return bool
     */
    public static function isAssoc($arr)
    {
        return array_keys($arr) !== range(0, count($arr) - 1);
    }

    /**
     * 用户名验证
     *
     * @param $username
     * @desc 用户名由2-16位数字或字母、汉字、下划线组成！
     * @return array
     */
    public static function checkUsernameValid($username)
    {
        if (preg_match('/^[A-Za-z0-9_\x{4e00}-\x{9fa5}]+$/u', $username)) {
            return ['code' => 1];
        } else {
            return ['code' => 0, 'message' => "用户名由2-16位数字或字母、汉字、下划线组成！"];
        }
    }

    /**
     * 判断手机号码是否正确
     *
     * @param $mobile
     * @return bool
     */
    public static function checkMobileValid($mobile)
    {
        if (!preg_match('/^((13[0-9])|(14[5|7])|(15([0-3]|[5-9]))|(17([0-9]))|(18[0-9]))\\d{8}$/', $mobile)) {
            return false;
        }
        return true;
    }

    /**
     * 验证电话号码是否正确
     *
     * @param $phone
     * @return bool
     */
    public static function checkPhoneValid($phone)
    {
        return (preg_match("/^(010|02\d{1}|0[3-9]\d{2})-\d{7,9}(-\d+)?$/", $phone)) ? true : false;
    }

    /**
     * 判断qq号码是否正确
     *
     * @param $qq
     * @return bool
     */
    public static function checkQQValid($qq)
    {
        if (!preg_match('/^[1-9][0-9]{4,12}$/', $qq)) {
            return false;
        }
        return true;
    }

    /**
     *  验证url是否正确
     *
     * @param $url
     * @return bool
     */
    public static function checkUrlValid($url)
    {
        $preg_str = '/^http[s]?:\/\/' .
            '(([0-9]{1,3}\.){3}[0-9]{1,3}' . // IP形式的URL- 199.194.52.184
            '|' . // 允许IP和DOMAIN（域名）
            '([0-9a-z_!~*\'()-]+\.)*' . // 域名- www.
            '([0-9a-z][0-9a-z-]{0,61})?[0-9a-z]\.' . // 二级域名
            '[a-z]{2,6})' .  // first level domain- .com or .museum
            '(:[0-9]{1,4})?' .  // 端口- :80
            '((\/\?)|' .  // a slash isn't required if there is no file name
            '(\/[0-9a-zA-Z_!~\'\(\)\[\]\.;\?:@&=\+\$,%#-\/^\*\|]*)?)$/';
        if (!preg_match($preg_str, $url)) {
            return false;
        }
        return true;
    }

    /**
     * 验证邮箱是否正确
     *
     * @param $email
     * @return bool
     */
    public static function checkEmailValid($email)
    {
        $preg_str = '/^([0-9A-Za-z\\-_\\.]+)@([0-9a-z]+\\.[a-z]{2,3}(\\.[a-z]{2})?)$/i';
        if (!preg_match($preg_str, $email)) {
            return false;
        }
        return true;
    }

    /**
     * 从Ip地址获取城市信息
     *
     * @param $ip
     * @param $type 0默认1直接显示城市
     * @return bool|mixed
     */
    public static function getCityFromIp($ip, $type = 0)
    {
        $res = @file_get_contents('http://int.dpool.sina.com.cn/iplookup/iplookup.php?format=js&ip=' . $ip);
        if (empty($res)) {
            return false;
        }
        $jsonMatches = array();
        preg_match('#\{.+?\}#', $res, $jsonMatches);
        if (!isset($jsonMatches[0])) {
            return false;
        }
        $json = json_decode($jsonMatches[0], true);
        if (isset($json['ret']) && $json['ret'] == 1) {
            $json['ip'] = $ip;
            unset($json['ret']);
        } else {
            return false;
        }
        if ($type == 1) {
            $province = isset($json['province']) ? $json['province'] : "";
            $city = isset($json['city']) ? $json['city'] : "";
            return $province . " " . $city;
        }
        return $json;
    }

    /**
     * 生成订单编号
     *
     * @param $type 订单类型
     * @return string
     */
    public static function createOrderNo($type = '')
    {
        return $type . date('YmdHis', time()) . rand(100000, 999999);
    }

    /**
     * 日期格式转换
     *
     * @param int $time
     * @param string $format
     * @return false|string
     */
    public static function toDate($time = 0, $format = 'Y-m-d H:i:s')
    {
        if ($time == 0) {
            return date('Y-m-d H:i:s', time());
        } else {
            return date($format, $time);
        }
    }

    /**
     * 将字符部分加密并输出
     * @param string $str
     * @param int $start 从第几个位置开始加密(从1开始)
     * @param int $length 连续加密多少位
     * @return string
     */
    public static function encryptShow($str, $start = 1, $length = 4)
    {
        //判断是否为邮箱
        $reg_email = '/(^[\s]*[a-zA-Z0-9._%-]+)@([a-zA-Z0-9._%-]+\.[a-zA-Z0-9]{2,4}[\s]*)$/';
        $is_email = 0;
        if (preg_match($reg_email, $str, $patchs)) {//如果是邮箱，则获取邮箱前部分
            $str = $patchs[1];
            $is_email = 1;
        }
        $end = $start - 1 + $length;
        $array = str_split($str);
        foreach ($array as $k => $v) {
            if ($k >= $start - 1 && $k < $end) {
                $array[$k] = '*';
            }
        }
        if ($is_email) {
            return implode('', $array) . '@' . $patchs[2];
        } else {
            return implode('', $array);
        }
    }


    /**
     * 身份证验证
     * @param $id_card身份证号码
     */
    public static function validation_filter_id_card($id_card)
    {
        if (strlen($id_card) == 18) {
            return self::_idcard_checksum18($id_card);
        } elseif ((strlen($id_card) == 15)) {
            $id_card = self::_idcard_15to18($id_card);
            return self::_idcard_checksum18($id_card);
        } else {
            return false;
        }
    }

// 计算身份证校验码，根据国家标准GB 11643-1999
    public static function _idcard_verify_number($idcard_base)
    {
        if (strlen($idcard_base) != 17) {
            return false;
        }
        //加权因子
        $factor = array(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2);
        //校验码对应值
        $verify_number_list = array('1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2');
        $checksum = 0;
        for ($i = 0; $i < strlen($idcard_base); $i++) {
            $checksum += substr($idcard_base, $i, 1) * $factor[$i];
        }
        $mod = $checksum % 11;
        $verify_number = $verify_number_list[$mod];
        return $verify_number;
    }

// 将15位身份证升级到18位
    public static function _idcard_15to18($idcard)
    {
        if (strlen($idcard) != 15) {
            return false;
        } else {
            // 如果身份证顺序码是996 997 998 999，这些是为百岁以上老人的特殊编码
            if (array_search(substr($idcard, 12, 3), array('996', '997', '998', '999')) !== false) {
                $idcard = substr($idcard, 0, 6) . '18' . substr($idcard, 6, 9);
            } else {
                $idcard = substr($idcard, 0, 6) . '19' . substr($idcard, 6, 9);
            }
        }
        $idcard = $idcard . self::_idcard_verify_number($idcard);
    }

// 18位身份证校验码有效性检查
    public static function _idcard_checksum18($idcard)
    {
        if (strlen($idcard) != 18) {
            return false;
        }
        $idcard_base = substr($idcard, 0, 17);
        if (self::_idcard_verify_number($idcard_base) != strtoupper(substr($idcard, 17, 1))) {
            return false;
        } else {
            return true;
        }
    }

    /**
     * 上传图片到远程
     *
     * @param $srcPath
     * @param $dstPath
     * @param int $type 1腾讯2阿里云
     * @param string $bucket
     * @return array
     */
    public static function uploadImageToRemote($srcPath, $dstPath,$oldPath='')
    {
        $result = ['code' => 1, 'message' => '', 'url' => ''];
        $type = env('UPLOAD_REMOTE_TYPE', 1);//默认1是腾讯COS
        if($type){
            try {
                $bucket = $type == 1 ? env('QCLODE_COS_BUCKET', 'image') : env('ALIYUN_OSS_BUCKET', 'xm-image');
                $filename = basename($srcPath);
                if ($type == 1) {//腾讯云COS
                    $return = QcloudCos::upload($bucket, $srcPath, $dstPath . '/' . $filename);
                    $return = json_decode($return, true);
                    if (!is_null($return) && $return['code'] == 0) {
                        $result['url'] = $return['data']['source_url'];
                    } else {
                        $result['code'] = 0;
                        $result['message'] = '上传出错';
                    }
                } elseif ($type == 2) {//阿里云OSS
                    $file = new UploadedFile($srcPath, basename($filename));
                    $return = Storage::disk('oss')->putFile($dstPath, $file);
                    $result['url'] = "http://" . $bucket . '.' . env('ALIYUN_OSS_ENDPOINT', '') . '/' . $return;
                }
            } catch (\Exception $exception) {
                $result['code'] = 0;
                $result['message'] = $exception->getMessage();
            }
        }else{
            $result['url'] = $oldPath;
        }
        return $result;
    }

    /**
     * 生成海报地址
     *
     * @param $bg_url //背景图片链接地址
     * @param $url //推广链接地址
     * @param array $position [type=>类型,'x','y']
     * @param int $size 二维码图片大小
     * @return array 用户的海报url
     */
    public static function createPoster($bg_url, $url, $position = [], $size = 200)
    {
        $filename = storage_path(md5(rand(10000, 999999)) . '.png');
        $client = new Client();
        $bgResponse = $client->get($bg_url);
        $content = $bgResponse->getBody()->getContents();
        $bg_image = Image::make($content);
        //根据地址生成二维码数据
        $qrcode = QrCode::format('png')->size($size)->margin(1)->generate($url);
        $type = isset($position['type']) ? $position['type'] : 'top';
        $x = isset($position['x']) ? $position['x'] : 0;
        $y = isset($position['y']) ? $position['y'] : 0;
        $abc = $bg_image->insert($qrcode, $type, $x, $y)->save($filename);
        try {
            $path = env('ALI_OSS_DIR') . '/' . date('Ym');
            $image_url = Storage::disk('oss')->putFile($path, new File($filename));
            $url = env('ALI_OSS_CDN_DOMAIN') . '/' . $image_url;
            @unlink($filename);
            return ['url' => $url];
        } catch (\Exception $exception) {
            return ['error_message' => '生成海报失败' . $exception->getMessage()];
        }
    }
}